"""
参数管理
此外，我们需要提取参数，一边再其他环境中复用他们
或者将模型保存下来，一边他可以在其它软件中执行
"""

import tensorflow as tf

if __name__ == '__main__':
    net = tf.keras.models.Sequential([
        tf.keras.layers.Flatten(),
        tf.keras.layers.Dense(4, activation=tf.nn.relu),
        tf.keras.layers.Dense(1),
    ])
    X = tf.random.uniform((2, 4))
    # 下面这一行不能注释
    net(X)
    # print(net(X))

    # [0]是Flatten，空
    # [1]是Dense(4)
    # [2]是Dense(1),weights查看权重
    # print(net.layers[1].weights)

    # 目标参数
    # 提取后返回参数类的实例子，并进一步访问改参数的值。
    # print(type(net.layers[2].weights[1]))
    # print(net.layers[2].weights[1])
    # print(tf.convert_to_tensor(net.layers[2].weights[1]))

    # 一次性访问所有参数
    # 只访问第一个全连接层
    # print(net.layers[2].weights)

    # 访问所有层的所有参数
    # print(net.get_weights())

    # 另外一中访问网络参数的方式，似乎序号是错误的
    # print(net.get_weights()[1])

    # 从嵌套块收集参数
    def block1(name):
        return tf.keras.Sequential([
            tf.keras.layers.Flatten(),
            tf.keras.layers.Dense(4, activation=tf.nn.relu)],
            name=name)
        
    def block2():
        net = tf.keras.Sequential()
        for i in range(4):
            # 在这里嵌套
            net.add(block1(name=f'block-{i}'))
        return net

    rgnet = tf.keras.Sequential()
    rgnet.add(block2())
    rgnet.add(tf.keras.layers.Dense(1))
    # print(rgnet(X))
    # # block2
    # print(rgnet.layers[0])
    # # block1第二个
    # print(rgnet.layers[0].layers[1])
    # # block1中Dense层
    # print(rgnet.layers[0].layers[1].layers[1])


    # 还可以将所有参数初始化为给定的参数比如初始化为1
    




